/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.sys.service;

import cn.hutool.core.util.ObjectUtil;
import com.jeeplus.common.utils.CacheUtils;
import com.jeeplus.common.utils.Encodes;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.core.security.Digests;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.core.service.ServiceException;
import com.jeeplus.modules.defaultscore.entity.DefaultScore;
import com.jeeplus.modules.defaultscore.service.DefaultScoreService;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.Role;
import com.jeeplus.modules.sys.entity.StudentMoreduMain;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.mapper.UserMapper;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * 用户管理
 * @author jeeplus
 * @version 2016-12-05
 */
@Service
@Transactional(readOnly = true)
public class UserService  extends CrudService<UserMapper, User> {
	@Autowired
	public static final String HASH_ALGORITHM = "SHA-1";
	public static final int HASH_INTERATIONS = 1024;
	public static final int SALT_SIZE = 8;
	private static final int BATCH_SIZE = 500;

	@Autowired
	private RedisTemplate<String,Object> redisTemplateObject;

	@Resource
	StudentMoreduMainService studentMoreduMainService;
	@Autowired
	DefaultScoreService defaultScoreService;
	/**
	 * 获取用户
	 * @param id
	 * @return
	 */
	public User get(String id) {
		return UserUtils.get(id);
	}

	/**
	 * 根据登录名获取用户
	 * @param loginName
	 * @return
	 */
	public User getUserByLoginName(String loginName) {
		return UserUtils.getByLoginName(loginName);
	}


	/**
	 * 通过部门ID获取用户列表，仅返回用户id和name（树查询用户时用）
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<User> findUserByOfficeId(String officeId) {
		List<User> list = (List<User>)CacheUtils.get(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + officeId);
		if (list == null){
			User user = new User();
			user.setOffice(new Office(officeId));
			list = mapper.findUserByOfficeId(user);
			CacheUtils.put(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + officeId, list);
		}
		return list;
	}

	@Transactional(readOnly = false)
	public void saveUser(User user, List<User> insertUserList, List<User> updateUserListById) {
		if (StringUtils.isBlank(user.getId())){
			user.preInsert();
//			mapper.insert(user);
			insertUserList.add(user);
			boolean a = false;
			if (user.getRoleList() != null) {
				for (Role role : user.getRoleList()) {
					if (role.getName().equals("学生账号")) {
						a = true;
					}
				}
				if (a == true) {
					StudentMoreduMain studentMoreduMain = new StudentMoreduMain();
					studentMoreduMain.setName(user.getName());  //姓名
					studentMoreduMain.setInstitute(user.getOffice().getName()); //学院
					studentMoreduMain.setGrade(user.getGrade()); //年级
					studentMoreduMain.setClasse(user.getClassn());  //班级
					studentMoreduMain.setStudentId(user.getNo());  //学号
					studentMoreduMain.setState(user.getState()); // 学籍状态
					studentMoreduMain.setCurrentInstructor(user.getTeacher());  //班级
					List<DefaultScore> defaultScoreList = defaultScoreService.findList(new DefaultScore()); // 查询默认分数
//					Integer.parseInt(defaultScoreList.get(0).getDefaultScore());
					studentMoreduMain.setCurrentMoraleduPoint(0); //德育分 基础分老师设定
					studentMoreduMainService.save(studentMoreduMain);
				}
			}
		}else{
			// 清除原用户机构用户缓存
			User oldUser = mapper.get(user.getId());
			if (oldUser.getOffice() != null && oldUser.getOffice().getId() != null){
				CacheUtils.remove(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + oldUser.getOffice().getId());
			}
			// 更新用户数据
			user.preUpdate();
//			mapper.update(user);
			updateUserListById.add(user);
		}
		if (StringUtils.isNotBlank(user.getId())){
			// 更新用户与角色关联
			mapper.deleteUserRole(user);
			if (user.getRoleList() != null && user.getRoleList().size() > 0){
				mapper.insertUserRole(user);
			}else{
				throw new ServiceException(user.getLoginName() + "没有设置角色！");
			}
			// 清除用户缓存
			UserUtils.clearCache(user);
		}
	}

	@Transactional(readOnly = false)
	public void saveUser(User user) {
		deleteCache();
		if (StringUtils.isBlank(user.getId())){
			user.preInsert();
			mapper.insert(user);
			boolean a = false;
			if (user.getRoleList() != null) {
				for (Role role : user.getRoleList()) {
					if (role.getName().equals("学生账号")) {
						a = true;
					}
				}
				if (a == true) {
					StudentMoreduMain studentMoreduMain = new StudentMoreduMain();
					studentMoreduMain.setName(user.getName());  //姓名
					studentMoreduMain.setInstitute(user.getOffice().getName()); //学院
					studentMoreduMain.setGrade(user.getGrade()); //年级
					studentMoreduMain.setClasse(user.getClassn());  //班级
					studentMoreduMain.setStudentId(user.getNo());  //学号
					studentMoreduMain.setState(user.getState()); // 学籍状态
					studentMoreduMain.setCurrentInstructor(user.getTeacher());  //班级
					List<DefaultScore> defaultScoreList = defaultScoreService.findList(new DefaultScore()); // 查询默认分数
//					Integer.parseInt(defaultScoreList.get(0).getDefaultScore());
					studentMoreduMain.setCurrentMoraleduPoint(0); //德育分 基础分老师设定
					studentMoreduMainService.save(studentMoreduMain);
				}
			}
		}else{
			// 清除原用户机构用户缓存
			User oldUser = mapper.get(user.getId());
			if (oldUser.getOffice() != null && oldUser.getOffice().getId() != null){
				CacheUtils.remove(UserUtils.USER_CACHE, UserUtils.USER_CACHE_LIST_BY_OFFICE_ID_ + oldUser.getOffice().getId());
			}

			// 更新用户数据
			user.preUpdate();
			mapper.update(user);
		}
		if (StringUtils.isNotBlank(user.getId())){
			// 更新用户与角色关联
			mapper.deleteUserRole(user);
			if (user.getRoleList() != null && user.getRoleList().size() > 0){
				mapper.insertUserRole(user);
			}else{
				throw new ServiceException(user.getLoginName() + "没有设置角色！");
			}
			// 清除用户缓存
			UserUtils.clearCache(user);
		}

	}

	@Transactional(readOnly = false)
	public void updateUserInfo(User user) {
		user.preUpdate();
		mapper.updateUserInfo(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
	}

	@Transactional(readOnly = false)
	public void deleteUser(User user) {
		mapper.deleteUserRole(user);
		mapper.delete(user);
		// 清除用户缓存
		UserUtils.clearCache(user);
	}

	@Transactional(readOnly = false)
	public void updatePasswordById(String id, String loginName, String newPassword) {
		User user = new User(id);
		user.setPassword(entryptPassword(newPassword));
		mapper.updatePasswordById(user);
		// 清除用户缓存
		user.setLoginName(loginName);
		UserUtils.clearCache(user);
	}

	@Transactional(readOnly = false)
	public void updateUserLoginInfo(User user) {
		// 保存上次登录信息
		user.setOldLoginIp(user.getLoginIp());
		user.setOldLoginDate(user.getLoginDate());
		// 更新本次登录信息
		user.setLoginIp(UserUtils.getSession().getHost());
		user.setLoginDate(new Date());
		mapper.updateLoginInfo(user);
	}

	/**
	 * 生成安全的密码，生成随机的16位salt并经过1024次 sha-1 hash
	 */
	public static String entryptPassword(String plainPassword) {
		byte[] salt = Digests.generateSalt(SALT_SIZE);
		byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword);
	}

	/**
	 * 验证密码
	 * @param plainPassword 明文密码
	 * @param password 密文密码
	 * @return 验证成功返回true
	 */
	public static boolean validatePassword(String plainPassword, String password) {
		byte[] salt = Encodes.decodeHex(password.substring(0,16));
		byte[] hashPassword = Digests.sha1(plainPassword.getBytes(), salt, HASH_INTERATIONS);
		return password.equals(Encodes.encodeHex(salt)+Encodes.encodeHex(hashPassword));
	}
	@Transactional(readOnly = false)
	public void updateLoginByGrade (User user){
		mapper.updateLoginByGrade(user);
		return;
	}

	/**
	 * 批量插入用户数据
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void batchInsert(List<User> user){
		int totalSize = user.size();
		int fromIndex = 0;
		int toIndex = Math.min(BATCH_SIZE, totalSize);

		while (fromIndex < totalSize) {
			List<User> sublist = user.subList(fromIndex, toIndex);
			mapper.batchInsert(sublist);

			fromIndex = toIndex;
			toIndex = Math.min(toIndex + BATCH_SIZE, totalSize);
		}
	}

	/**
	 * 批量更新用户数据
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void batchUpdateById(List<User> user){
		int totalSize = user.size();
		int fromIndex = 0;
		int toIndex = Math.min(BATCH_SIZE, totalSize);

		while (fromIndex < totalSize) {
			List<User> sublist = user.subList(fromIndex, toIndex);
			mapper.batchUpdate(sublist);

			fromIndex = toIndex;
			toIndex = Math.min(toIndex + BATCH_SIZE, totalSize);
		}
	}

	/**
	 * 批量更新用户数据
	 * @param user
	 */
	@Transactional(readOnly = false)
	public void batchUpdateByNo(List<User> user){
		int totalSize = user.size();
		int fromIndex = 0;
		int toIndex = Math.min(BATCH_SIZE, totalSize);

		while (fromIndex < totalSize) {
			List<User> sublist = user.subList(fromIndex, toIndex);
			mapper.batchUpdateNo(sublist);

			fromIndex = toIndex;
			toIndex = Math.min(toIndex + BATCH_SIZE, totalSize);
		}
	}

	public void deleteCache () {
		String keyPre = "StudentMoreduMain";
		Set keys = redisTemplateObject.keys(keyPre + "*");
		if (ObjectUtil.isNotEmpty(keys)) {
			redisTemplateObject.delete(keys);
		}
	}


}
